﻿// Buffer.h

#ifndef __GDK_BUFFER_H__
#define __GDK_BUFFER_H__

#include <gdk/core/Types.h>
#include <gdk/core/String.h>
#include <gdk/core/Property.h>
#include <gdk/core/Stream.h>
#include <gdk/core/Varint.h>


namespace gdk
{


class GDK_CORE_EXPORT Buffer
{
private:
	ssize_t	_size;
	char*	_buffer;

public:
	__INLINE__ Buffer(ssize_t size = 0)
	{
		_size = 0;
		_buffer = NULL;

		setBufferSize(size);
	}

	__INLINE__ Buffer(const Buffer &buf)
	{
		_size = 0;
		_buffer = NULL;

		this->operator =(buf);
	}

	__INLINE__ ~Buffer(void)
	{
		if(_buffer) GDK_DELETE [](_buffer);
	}

	ssize_t setBufferSize(ssize_t size);

	__INLINE__ ssize_t getBufferSize(void) const
	{
		return _size;
	}

	__INLINE__ void* getBuffer(void)
	{
		return _buffer;
	}

	__INLINE__ const void* getBuffer(void) const
	{
		return _buffer;
	}

	__INLINE__ Buffer& operator  =(const Buffer &buf)
	{
		if (buf.getBufferSize() == setBufferSize(buf.getBufferSize()))
		{
			memCopy(getBuffer(), buf.getBuffer(), getBufferSize());
		}
		return *this;
	}

	__INLINE__ bool operator  ==(const Buffer &r) const
	{
		return	_size == r._size &&
				(	_buffer == r._buffer ||
					memcmp(_buffer, r._buffer, _size) == 0
				);
	}
	__INLINE__ bool operator  !=(const Buffer &r) const
	{
		return !(*this == r);
	}

	__INLINE__ operator const void*() const
	{
		return _buffer;
	}

	__INLINE__ operator void*()
	{
		return _buffer;
	}

	String convertToHex(void) const;
	bool convertFromHex(const String &hex);

	String convertToBase64(void) const;
	bool convertFromBase64(const String &text);

public:
	template<typename TyIs> friend TyIs& operator >>(TyIs &is, Buffer &buf) __THROW1;
	template<typename TyOs> friend TyOs& operator <<(TyOs &os, const Buffer &buf) __THROW1;
};


template<typename TyIs>
TyIs& operator >>(TyIs &is, Buffer &buf) __THROW1
{
	Varint size;
	is >> size;

	if (size != buf.setBufferSize(size)
	||	size != is.read(buf.getBuffer(), size))
	{
		__THROW__(__TEXT__("TyIs& operator >>(TyIs &, Buffer &)"));
	}

	return is;
}
template<typename TyOs>
TyOs& operator <<(TyOs &os, const Buffer &buf) __THROW1
{
	Varint size = buf.getBufferSize();
	os << size;
	if (size != os.write(buf.getBuffer(), size))
	{
		__THROW__(__TEXT__("TyOs& operator <<(TyOs &, const Buffer &)"));
	}
	return os;
}

template GDK_CORE_EXPORT InputStream& operator>>(InputStream &is,Buffer &buf) __THROW1;
template GDK_CORE_EXPORT OutputStream& operator<<(OutputStream &os,Buffer const &buf) __THROW1;


//------------------------------------------------------------------------
__INLINE__ void convertPropertyToClass(const JsonValue &json, Buffer &buffer) __THROW1
{
	if (!json.isString() || !buffer.convertFromBase64(json.asString()))
	{
		__THROW__(__TEXT__("void convertPropertyToClass(const String &, Buffer &)"));
	}
}
__INLINE__ void convertPropertyToJson(const Buffer &buffer, JsonValue &json) __THROW1
{
	json = buffer.convertToBase64();
}


}


#endif //__GDK_BUFFER_H__
